引数でのimpl Trait
from impl Trait
RFC 1591
genericsのsyntax sugar
例
code:rust
fn print_name(name: impl AsRef<str>) {
println!("{}", name.as_ref());
}
これと同じ意味
code:rs
fn print_name<T: AsRef<str>>(name: T) {
println!("{}", name.as_ref());
}
こう説明されるとめっちゃわかりやすいなmrsekut.icon
AsRef<str> を実装している型なら何でも受け付けることを意味する
e.g. String, &str
これと同じことをdyn Traitでやるなら
fn print_name(name: &dyn AsRef<str>) になるが、
impl Trait は 静的ディスパッチ でオーバーヘッドが少ない
genericsより表現力が低い
impl Trait は関数ごとに独立して決定される
複数の impl Trait を受け取るとき、それらが同じ型かどうかを保証できない
code:rust
fn combine(a: impl Display, b: impl Display) { /* a と b が同じ型か不明 */ }
同じ型を強制するならジェネリクスを使う
code:rust
fn combine<T: Display>(a: T, b: T) { /* a と b は同じ型 */ }
安定化間近!Rustのimpl Traitを今こそ理解する - 簡潔なQ